// -----------------------------------------------------------------------
//  <copyright file="LogoutCommand.cs" company="LiuliuSoft">
//      Copyright (c) 2022-2024 DaprPlus. All rights reserved.
//  </copyright>
//  <site>https://www.dapr.plus</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2024-04-26 01:04</last-date>
// -----------------------------------------------------------------------

using System.Security.Claims;

using DaprPlus.Domain.Events;
using DaprPlus.Identity.Application;
using DaprPlus.Identity.Domain.Entities;

using DaprPlus.Identity.Application.Identity.Users.Events;

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;


namespace DaprPlus.Identity.Application.Identity.Users.Commands;

[AuthConfig(typeof(User), ResourceAccessType.Anonymous, "Logout")]
public class LogoutCommand : IRequest<ApiResult>, ICommand
{
    public ClaimsPrincipal Principal { get; set; } = null!;
}

public class LogoutCommandHandler(IServiceProvider provider) : IRequestHandler<LogoutCommand, ApiResult>
{
    public async Task<ApiResult> Handle(LogoutCommand request, CancellationToken token)
    {
        var principal = request.Principal;
        if (principal.Identity?.IsAuthenticated != true)
        {
            return ApiResult.Success("用户退出成功");
        }

        var userId = principal.Identity.GetUserId();
        var httpContext = provider.GetRequiredService<IHttpContextAccessor>().HttpContext;
        if (httpContext != null)
        {
            await httpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
        }

        var logoutDomainEvent = new UserLoggedOutDomainEvent() { UserId = userId };
        var domainEventBus = provider.GetRequiredService<IDomainEventBus>();
        await domainEventBus.PublishAsync(logoutDomainEvent, token);

        var logoutIntegrationEvent = new UserLoggedOutIntegrationEvent() { UserId = userId };
        var unitOfWork = provider.GetUnitOfWork();
        unitOfWork.AddIntegrationEvent(logoutIntegrationEvent);

        return ApiResult.Success();
    }
}

public class LogoutCommandValidator : AbstractValidator<LogoutCommand>
{
    public LogoutCommandValidator()
    {
        RuleFor(m => m != null);
    }
}

/*
名称：
作用：
需求点：

*/

